package JUC.pool;

import java.util.concurrent.*;

//Executors 工具类 3大方法
//使用线程池之后，使用线程池来创建线程
public class Demo01 {
    public static void main(String[] args) {
        //一个线程执行100个操作
        //ExecutorService threadPool = Executors.newSingleThreadExecutor();//单个线程
        //5个线程同时执行
        //ExecutorService threadPool =Executors.newFixedThreadPool(5);//创建固定的线程池大小
        //10个线程同时执行
        //ExecutorService threadPool =Executors.newCachedThreadPool();//可以伸缩的，遇强则强，遇弱则弱

        /**
         * new ThreadPoolExecutor.AbortPolicy()//拒绝策略,队列中服务线程满了，还有请求，不处理这个请求并抛出异常
         * new ThreadPoolExecutor.CallerRunsPolicy()//拒绝策略,队列中服务线程满了，还有请求，请求返回到请求原来所在的线程
         * new ThreadPoolExecutor.DiscardPolicy()//拒绝策略,队列中服务线程满了，还有请求，不会抛出异常，丢掉这次请求
         * new ThreadPoolExecutor.DiscardOldestPolicy()//拒绝策略,队列中服务线程满了，还有请求，尝试去和最早的请求线程竞争，如果竞争失败，不会抛出异常
         **/
        //自定义线程池

        //最大线程到底该如何定义
        //1.CPU密集型,几核CPU就是几，可以保证CPU效率最高
        // 获取CPU核数
        // System.out.println(Runtime.getRuntime().availableProcessors());

        //2.IO密集型
        //判断程序中十分耗IO的线程，大于IO线程



        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                2,
                5,
                3, TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardOldestPolicy()//拒绝策略,队列中服务线程满了，还有请求，尝试去和最早的请求线程竞争，如果竞争失败，不会抛出异常
                );


        //线程池用完要关闭
        try {
            //最大承载：队列数+最大线程数
            //超出最大承载就会抛出 java.util.concurrent.RejectedExecutionException
            for (int i = 1; i <= 77; i++) {
                //使用线程池创建线程
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "ok");
                });
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            threadPool.shutdown();
        }

    }
}
